#define _CRT_SECURE_NO_WARNINGS 1

// 类和对象

// 面向过程和面向对象初步认识
// C语言是面向过程，C++是面向对象

// 类的引入
// C语言结构体中只能定义变量，在C++中，结构体内不仅可以定义变量，也可以定义函数。
// 比如：之前在数据结构初阶中，用C语言方式实现的栈，结构体中只能定义变量；现在以C++方式实现，
// 会发现struct中也可以定义函数

//// C++兼容C中struct的用法
//// C++升级struct成了类
//#include <iostream>
//using namespace std;

//// 1.类里面可以定义函数了
//// 2.struct后面的名称就可以代表类型

//typedef int DataType;
//struct Stack
//{
//	// 成员函数
//	void Init(size_t capacity = 4)
//	{
//		_array = (DataType*)malloc(sizeof(DataType) * capacity);
//		if (nullptr == _array)
//		{
//			perror("malloc申请空间失败");
//			return;
//		}
//		_capacity = capacity;
//		_size = 0;
//	}
//
//	void Push(const DataType& data)
//	{
//		// 扩容
//		_array[_size] = data;
//		++_size;
//	}
//
//
//	DataType* _array;
//	size_t  _capacity;
//	size_t _size;
//};
//
//int main()
//{
//	struct Stack st1;
//	st1.Init(100);
//
//	Stack st2;
//	st2.Init();
//
//	return 0;
//}


// 其实，C++更喜欢用class来定义类
//#include <iostream>
//using namespace std;
//
//typedef int DataType;
//class Stack
//{
//public:
//	// 成员函数
//	void Init(size_t capacity = 4)
//	{
//		_array = (DataType*)malloc(sizeof(DataType) * capacity);
//		if (nullptr == _array)
//		{
//			perror("malloc申请空间失败");
//			return;
//		}
//		_capacity = capacity;
//		_size = 0;
//	}
//
//	void Push(const DataType& data)
//	{
//		// ...扩容
//		_array[_size] = data;
//		++_size;
//	}
//
//	DataType top()
//	{
//		return _array[_size - 1];
//	}
//
//private:
//	DataType* _array;
//	size_t  _capacity;
//	size_t _size;
//};
//// 体现了封装，把数据和方法都放在一起
//// 再借助访问限定符
//
//int main()
//{
//	// class Stack st1;
//	Stack st2;
//
//	// public修饰的成员在类外可以直接被访问
//	// protected和private修饰的成员在类外不能直接被访问
//	// 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
//	// 否则就是到}结束
//	// class的默认访问权限为private，struct为public(兼容C)
//
//	/* error，私有不可访问 */
//	//st2.Init();
//	//st2.Push(1);
//	//st2.Push(2);
//	//st2.Push(3);
//	//st2.Push(4);
//
//	st2.Init();
//	st2.Push(1);
//	st2.Push(2);
//
//	cout << st2.top() << endl;
//
//	return 0;
//}

#include "Stack.h"

// 类中仅有成员函数
class A2 {
public:
	void f2() {}
};

// 类中什么都没有---空类
class A3
{};


//int main()
//{
//	// 类是对对象进行描述的，是一个模型一样的东西，限定了类有哪些成员，
//	// 定义出一个类并没有分配实际的内存空间来存储它
//	// 实例化出的对象 占用实际的物理空间 ，存储 类成员变量 
//	
//	//Date d; // 对象的实例化
//	//d.Init(2024, 9, 18);
//
//	Stack st1;
//	Stack st2;
//
//	cout << sizeof(st1) << endl;
//	cout << sizeof(Stack) << endl; // 房子没造出来，但是也能看图纸看到多少平方
//  // 注意内存对齐
//	// sizeof(Stack) 也可以计算出来
//
//	// 其实我们可以发现，我们是不算成员函数的，只算成员变量
//	st1.Init();
//	st2.Init();
//	// 我们想，两者的成员变量当然不同
//	// 可是调的函数如Init都是一样的，函数指针都是一样的
//	// 如果存放在每一个对象，就很浪费空间，实例化一百个对象，就多用九十九份内存
//	// 
//	// 打个比方，按照图纸设计每个房间，每个房间都需要客厅、卧室、厕所，这是必需的
//	// 可是公园、泳池就没必要每家一个，大家公用一个就行
//	// 成员函数也是存放在公共区域
//
//	A3 aa1; // 定义，开了空间
//	// 会给一个字节，不存储有效数据，标识对象被定义出来了
//	cout << sizeof(A3) << endl; // 1，尽管它是空类
//	cout << sizeof(A2) << endl; // 1，成员函数不存在变量里面
//
//
//	return 0;
//}

//int main()
//{
//	Date d1;
//	Date d2;
//
//	d1.Init(2024, 9, 18);
//	d1.Init(2024, 9, 19);
//
//	// 调用的都是同一个函数，却打印出不同的数值
//	// 这是隐含的 this 指针
//	// 注释掉的部分就是编译器的处理
//	d1.Print(); // d1.Print(&d1); 
//	d2.Print(); // d2.Print(&d2);
//	// 1.实参和形参的位置不能显示写，编译器自己加
//	// 2.但是在类里面可以用
//	
//	// 对象里面只有成员变量
//	return 0;
//}

// 来个this指针的具体例子
//class A
//{
//public:
//	void Print()
//	{
//		cout << "Print()" << endl;
//	}
//private:
//	int _a;
//};
//int main()
//{
//	A* p = nullptr;
//	p->Print(); // 可以正常输出Print()
//
//	return 0;
//}

//class A
//{
//public:
//	void PrintA()
//	{
//		// 编译器会改成
//		// cout << this->_a << endl; // 空指针调用了
//		cout << _a << endl;
//	}
//private:
//	int _a;
//};
//int main()
//{
//	A* p = nullptr;
//	p->PrintA();
//
//	return 0;
//}

// C++中 Stack* 参数是编译器维护的，C语言中需用用户自己维护
// this指针存在栈里面，因为是形参
// 也有可能存在ecx，图效率














